package com.naiterui.ehp.bs.cms.modules.followup.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.naiterui.ehp.bp.bo.emr.QaPageBO;
import com.naiterui.ehp.bp.bo.followup.DrFollowUpRecordFormBO;
import com.naiterui.ehp.bp.bo.followup.FollowUpFormBO;
import com.naiterui.ehp.bp.bo.form.DesignFormBO;
import com.naiterui.ehp.bp.bo.form.FormConfBO;
import com.naiterui.ehp.bp.bo.form.FormDrawingBO;
import com.naiterui.ehp.bp.security.utils.BaseJwtUser;
import com.naiterui.ehp.bp.security.utils.SecurityUtils;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bs.cms.common.exception.BusinessExceptionCode;
import com.naiterui.ehp.bs.cms.common.utils.DateUtils;
import com.naiterui.ehp.bs.cms.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.cms.common.vo.PageVO;
import com.naiterui.ehp.bs.cms.modules.followup.entity.FollowUpForm;
import com.naiterui.ehp.bs.cms.modules.followup.entity.FollowUpRecordForm;
import com.naiterui.ehp.bs.cms.modules.followup.feign.DesignFormFeignClient;
import com.naiterui.ehp.bs.cms.modules.followup.feign.PatientFeignClient;
import com.naiterui.ehp.bs.cms.modules.followup.mapper.FollowUpFormMapper;
import com.naiterui.ehp.bs.cms.modules.followup.mapper.FollowUpFormRecordMapper;
import com.naiterui.ehp.bs.cms.modules.followup.service.IFollowUpFormService;
import com.naiterui.ehp.bs.cms.modules.followup.vo.FollowUpFormDetailVO;
import com.naiterui.ehp.bs.cms.modules.followup.vo.FollowUpFormVO;
import com.naiterui.ehp.bs.cms.modules.followup.vo.FollowUpRecordFormVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yangfuya
 * @since 2022/1/5
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FollowUpFormServiceImpl extends ServiceImpl<FollowUpFormMapper, FollowUpForm>
        implements IFollowUpFormService {

    private final DesignFormFeignClient designFormFeignClient;

    private final PatientFeignClient patientFeignClient;


    private final FollowUpFormRecordMapper recordMapper;


    @Override
    public PageVO<FollowUpFormVO> queryPage(PageParamsVO pageParamsVO, FollowUpFormVO followUpFormVO) {
        QueryWrapper<FollowUpForm> entityWrapper = new QueryWrapper<>();
        String name = followUpFormVO.getName();
        entityWrapper.like(StringUtils.isNotBlank(name), "name", name);
        Integer type = followUpFormVO.getType();
        entityWrapper.eq(type != null, "type", type);
        entityWrapper.eq("del_flag", 0);
        entityWrapper.orderByDesc("created_at");
        Page<FollowUpFormVO> page = this.baseMapper.getPage(pageParamsVO.getPage(), entityWrapper);
        List<FollowUpFormVO> records = page.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            Long currentUserId = SecurityUtils.getCurrentUser().getId();
            page.setRecords(records.stream().map(r -> {
                r.setIsself(r.getUserId().equals(currentUserId) ? 1 : 0);
                return r;
            }).collect(Collectors.toList()));
        }
        return PageVO.toPageVo(page);
    }

    @Override
    public void edit(FollowUpFormBO followUpFormBO) throws BusinessException {
        if (followUpFormBO.getFormId() != null && followUpFormBO.getFormId().equals("undefined")) {
            throw new BusinessException(BusinessExceptionCode.PARAM_ERROR);
        }
        DesignFormBO designForm = new DesignFormBO();
        // 表单配置
        FormConfBO formConf = new FormConfBO();
        formConf.setTitle(followUpFormBO.getName());
        designForm.setFormConf(formConf);
        designForm.setFormDrawing(followUpFormBO.getFormDrawing());
        String formId = this.designFormFeignClient.formDesign(designForm);
        Long id = followUpFormBO.getId();
        followUpFormBO.setFormId(formId);
        // 保存
        if (id == null) {
            this.save(followUpFormBO);
        }
        // 修改
        else {
            this.update(followUpFormBO);
        }
    }

    @Override
    public FollowUpFormDetailVO getById(Long id) throws BusinessException {
        FollowUpForm followUpForm = this.baseMapper.selectById(id);
        if (followUpForm == null) {
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_IS_NULL);
        }
        Long userId = followUpForm.getUserId();
        Long currentUserId = SecurityUtils.getCurrentUser().getId();
        if (!userId.equals(currentUserId)) {
            log.info("此表单不是您创建的, userId: {}, currentUserId: {}", userId, currentUserId);
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_NOT_YOU);
        }
        FollowUpFormDetailVO followUpFormVO = new FollowUpFormDetailVO();
        BeanUtil.copyProperties(followUpForm, followUpFormVO);
        DesignFormBO designForm = this.designFormFeignClient.getDesignForm(followUpForm.getFormId());
        followUpFormVO.setFormDrawing(designForm.getFormDrawing());
        return followUpFormVO;
    }

    @Override
    public String upload(MultipartFile file) throws BusinessException {
        String filePath = this.designFormFeignClient.upload(file);
        return filePath;
    }

    @Override
    public List<FormDrawingBO> getDesignForm(String formId) throws BusinessException {
        DesignFormBO designForm = this.designFormFeignClient.getDesignForm(formId);
        return designForm.getFormDrawing();
    }

    @Override
    public void deleteById(Long id) throws BusinessException {
        FollowUpForm followUpForm = this.baseMapper.selectById(id);
        if (followUpForm == null) {
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_IS_NULL);
        }
        Long userId = followUpForm.getUserId();
        Long currentUserId = SecurityUtils.getCurrentUser().getId();
        if (!userId.equals(currentUserId)) {
            log.info("此表单不是您创建的, userId: {}, currentUserId: {}", userId, currentUserId);
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_NOT_YOU);
        }
        followUpForm.setDelFlag(1);
        this.baseMapper.updateById(followUpForm);
    }

    @Override
    public void updateStatus(Long id, Integer status) throws BusinessException {
        FollowUpForm followUpForm = this.baseMapper.selectById(id);
        if (followUpForm == null) {
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_IS_NULL);
        }
        Long userId = followUpForm.getUserId();
        Long currentUserId = SecurityUtils.getCurrentUser().getId();
        if (!userId.equals(currentUserId)) {
            log.info("此表单不是您创建的, userId: {}, currentUserId: {}", userId, currentUserId);
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_NOT_YOU);
        }
        followUpForm.setStatus(status);
        this.baseMapper.updateById(followUpForm);
    }

    @Override
    public QaPageBO qaRecord(Long qaId, String name, Integer fillingStatus, PageParamsVO pageParamsVO) throws BusinessException {
        FollowUpForm followUpForm = this.baseMapper.selectById(qaId);
        QueryWrapper<FollowUpRecordFormVO> entityWrapper = new QueryWrapper<>();
        String createdAt = Joiner.on(".").skipNulls().join("t", "submit_at");
        entityWrapper.ge(StringUtils.isNotBlank(pageParamsVO.getDateGte()), createdAt, pageParamsVO.getDateGte());
        if (StringUtils.isNotBlank(pageParamsVO.getDateLte())) {
            Date plus = DateUtils.plus(DateUtils.parseStrToDate(pageParamsVO.getDateLte()), 1, ChronoUnit.DAYS);
            entityWrapper.le(createdAt, plus);
        }
        entityWrapper.like(StringUtils.isNotBlank(name), "ur.inquirer_name", name);
        entityWrapper.eq(fillingStatus != null && (fillingStatus == 0 || fillingStatus == 1), "t.filling_status", fillingStatus);
        entityWrapper.eq(qaId != null, "t.follow_up_form_id", qaId);
        Page<FollowUpRecordFormVO> page = this.recordMapper.getPage(pageParamsVO.getPage(), entityWrapper);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return QaPageBO.builder()
                    .pageNo((int) page.getCurrent())
                    .pageSize((int) page.getSize())
                    .title(followUpForm.getName())
                    .view("")
                    .statisTime(new Date())
                    .completePercent("0%")
                    .totalNumber(0L)
                    .notFilledNumber(0L)
                    .filledNumber(0L)
                    .exportUrl("")
                    .build();
        } else {
            QaPageBO result = patientFeignClient.qaRecord(page.getRecords());
            result.setPageNo((int) page.getCurrent());
            result.setPageSize((int) page.getSize());
            return result;
        }
    }

    @Override
    public byte[] qaRecordExport(Long qaId, String name, Integer fillingStatus, PageParamsVO pageParamsVO) throws BusinessException {
        byte[] workbook = null;
        QueryWrapper<FollowUpRecordFormVO> entityWrapper = pageParamsVO.getEntityWrapper("t");
        entityWrapper.like(StringUtils.isNotBlank(name), "ur.name", name);
        entityWrapper.eq(fillingStatus != null && (fillingStatus == 0 || fillingStatus == 1), "t.filling_status", fillingStatus);
        entityWrapper.eq(qaId != null, "t.follow_up_form_id", qaId);
        List<FollowUpRecordFormVO> page = this.recordMapper.getRecordList(entityWrapper);
        if (CollectionUtils.isEmpty(page)) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "数据不存在");
        } else {
            workbook = patientFeignClient.qaRecordExport(page);
        }
        return workbook;
    }

    @Override
    public DrFollowUpRecordFormBO qaRecordDetail(Long followUpRecordFormId) throws BusinessException {
        FollowUpRecordForm followUpRecordForm = this.recordMapper.selectById(followUpRecordFormId);
        if (followUpRecordForm == null) {
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_RECORD_NOT_EXIST);
        }
        DesignFormBO designForm =
                designFormFeignClient.getDesignFormDataVO(followUpRecordForm.getFormId(), followUpRecordFormId.toString());
        return DrFollowUpRecordFormBO.builder().followUpRecordFormId(followUpRecordFormId)
                .followUpFormId(followUpRecordForm.getFollowUpFormId()).formName(followUpRecordForm.getFormName())
                .fillingStatus(followUpRecordForm.getFillingStatus()).designForm(designForm).build();
    }

    private void save(FollowUpFormBO followUpFormBO) {
        BaseJwtUser currentUser = SecurityUtils.getCurrentUser();
        FollowUpForm followUpForm = new FollowUpForm();
        followUpForm.setFormId(followUpFormBO.getFormId());
        followUpForm.setName(followUpFormBO.getName());
        followUpForm.setType(followUpFormBO.getType());
        // 默认所有人共享
        followUpForm.setDoctorId(0L);
        followUpForm.setStatus(0);
        followUpForm.setUserId(currentUser.getId());
        followUpForm.setCreatedBy(currentUser.getUsername());
        followUpForm.setChangedAt(new Date());
        followUpForm.setChangedBy(currentUser.getUsername());
        this.baseMapper.insert(followUpForm);
    }

    private void update(FollowUpFormBO followUpFormBO) throws BusinessException {
        FollowUpForm followUpForm = this.baseMapper.selectById(followUpFormBO.getId());
        if (followUpForm == null) {
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_IS_NULL);
        }
        Long userId = followUpForm.getUserId();
        Long currentUserId = SecurityUtils.getCurrentUser().getId();
        if (!userId.equals(currentUserId)) {
            log.info("此表单不是您创建的, userId: {}, currentUserId: {}", userId, currentUserId);
            throw new BusinessException(BaseExceptionCodes.FOLLOW_UP_FORM_NOT_YOU);
        }
        followUpForm.setFormId(followUpFormBO.getFormId());
        followUpForm.setName(followUpFormBO.getName());
        followUpForm.setType(followUpFormBO.getType());
        // 默认所有人共享
        followUpForm.setDoctorId(0L);
        followUpForm.setStatus(0);
        followUpForm.setChangedBy(SecurityUtils.getCurrentUser().getUsername());
        this.baseMapper.updateById(followUpForm);
    }
}
